package org.itboys.mobile.service.mysql.mobile.order;

import org.apache.commons.lang3.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.time.TimeUtils;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.commons.utils.tools.LongUtil;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.order.MdlOrderProductMapper;
import org.itboys.mobile.dao.product.SundayProductMapper;
import org.itboys.mobile.dto.count.MdlCountDto;
import org.itboys.mobile.dto.count.MdlCountProductDto;
import org.itboys.mobile.dto.order.MdlOrderDto;
import org.itboys.mobile.dto.order.MdlOrderProductDto;
import org.itboys.mobile.entity.mongo.SundayAddress;
import org.itboys.mobile.entity.mongo.SundayMember;
import org.itboys.mobile.entity.mysql.order.MdlOrder;
import org.itboys.mobile.entity.mysql.order.MdlOrderProduct;
import org.itboys.mobile.entity.mysql.product.SundayProduct;
import org.itboys.mobile.service.mongo.mobile.address.SundayMobileAddressService;
import org.itboys.mobile.service.mongo.mobile.cart.MdlMobileCartService;
import org.itboys.mobile.service.mongo.mobile.comment.MdlMobileCommentService;
import org.itboys.mobile.service.mongo.mobile.count.MdlMobileCountService;
import org.itboys.mobile.service.mongo.mobile.member.SundayMobileMemberService;
import org.itboys.mobile.service.mysql.mobile.income.MdlMobileIncomeService;
import org.itboys.mobile.util.NumberUtil;
import org.itboys.mongodb.service.BaseMySqlService;
import org.itboys.param.ParamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * 作者：zzq
 * 时间：2017/12/5
 * 描述：迈迪龙_手机_订单
 */
@Service
public class MdlMobileOrderService extends BaseMySqlService<MdlOrder>{
    @Autowired
    private MdlMobileCountService countService;
    @Autowired
    private SundayMobileAddressService addressService;
    @Autowired
    private SundayMobileMemberService memberService;
    @Autowired
    private MdlOrderProductMapper orderProductMapper;
    @Autowired
    private MdlMobileCartService cartService;
    @Autowired
    private MdlMobileCommentService commentService;
    @Autowired
    private MdlMobileIncomeService incomeService;

    /**
     * 创建订单  双版本通用
     * @param memberId
     * @param cartIds
     * @param addressId
     * @param remark
     * @return
     */
    @Transactional
    public Map<String,Object> createOrder(Long memberId, List<Long> cartIds,
                                           Long addressId,Integer sendType,
                                           String remark){
        Map<String,Object> result = new HashMap<String,Object>();
        String orderIds = "";//需要支付的订单
        String receiveName="";//收获信息
        String receiveMobile="";//收获信息
        String receiveAddress="";//收获信息
        Integer isNeedToPay=1;//订单是否需要支付。默认是
        SundayAddress address = null;
        String orderNo=null;
        //1校验参数签名
        //2获取购物车数据
        MdlCountDto countDto =countService.countCart(memberId,cartIds,null,sendType);
        //准备订单数据
        MdlOrder order = new MdlOrder();
        SundayMember member = memberService.getById(memberId);
        //2.1，商城订单
        if(countDto.getType()== SundayCommonConstants.type_mall){
            logger.info("--订单开始生成--商城订单");
            /*if(sendType==null){
                throw new ErrorException("请选择配送方式。");
            }*/
            orderNo= NumberUtil.generateNumber("MALL");

            //1，判断收货方式
            //order.setSendType(countDto.getSendType());
            //order.setSendAmount(countDto.getSendAmount());

                if(!LongUtil.isNotZreo(addressId)){
                    throw new ErrorException("缺少地址。");

                }

                address = addressService.getById(addressId);
                //2017年9月8日
                if(StringUtils.isEmpty(address.getReceiveAddress())){
                    throw new ErrorException("缺少详细地址。");
                }
                receiveName=address.getReceiveName();
                receiveMobile=address.getReceiveMobile();
                //商城订单收货地址：详细地址
                receiveAddress=address.getProvinceName()+address.getCityName()+address.getDistrictName()+address.getReceiveAddress();

                logger.info("商城订单--"+orderNo+"需要支付，开始创建");
                isNeedToPay=1;
                order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DFK);

        }
        //采购订单
        if(countDto.getType()== SundayCommonConstants.type_caigou){
            logger.info("--订单开始生成--采购订单");
            orderNo=NumberUtil.generateNumber("CG");
            if(!LongUtil.isNotZreo(addressId)){
                throw new ErrorException("请选择收货地址");
            }
            address = addressService.getById(addressId);

            isNeedToPay=1;
            order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DFK);

            receiveName=address.getReceiveName();
            receiveMobile=address.getReceiveMobile();
            //采购订单收货地址需要包含省市区县数据
            receiveAddress=address.getProvinceName()+address.getCityName()+address.getDistrictName()+address.getReceiveAddress();
            //返回需要支付的订单IDs。只针对需要支付的订单
            //采购订单-保持用户类型
            order.setUserType(member.getUserType());
        }

        order.setOrderNo(orderNo);
        order.setType(countDto.getType());
        order.setTotalAmount(countDto.getTotalAmount().add(countDto.getSendAmount()));
        order.setPayAmount(countDto.getPayAmount().add(countDto.getSendAmount()));
        order.setSendType(sendType);
        order.setSendAmount(countDto.getSendAmount());
        order.setReceiveName(receiveName);
        order.setReceiveMobile(receiveMobile);
        order.setReceiveAddress(receiveAddress);
        order.setMemberId(member.getId());
        order.setMemberName(member.getNickName());
        if(member.getUserType()!=SundayCommonConstants.USER_TYPE_AGENT){
            SundayMember agent=memberService.getById(member.getAgentId());
            order.setAgentId(agent.getId());
            order.setAgentName(agent.getNickName());
        }
        order.setRemark(remark);

        //保存订单
        super.insert(order);
        //保存订单商品
        List<Long> productIds=new ArrayList<Long>();
        //本次销售的商品数量
        List<Integer> sale_nums=new ArrayList<Integer>();
        List<MdlOrderProduct> orderProducts = new ArrayList<MdlOrderProduct>();
        for(MdlCountProductDto countProductDto:countDto.getProducts()){
            MdlOrderProduct orderProduct =
                    new MdlOrderProduct(order.getId(),countProductDto.getId(),
                            countProductDto.getPrice(), countProductDto.getName(),countProductDto.getNumber(),
                            countProductDto.getImage(),
                            countProductDto.getStandard(),countProductDto.getNum(), countProductDto.getType());
            orderProductMapper.insert(orderProduct);
            productIds.add(orderProduct.getProductId());
            sale_nums.add(orderProduct.getNum());
            orderProducts.add(orderProduct);
        }
        //删除购物车
        cartService.deleteCart(cartIds,memberId,null);
        //返回支付的订单ID集合
        if(isNeedToPay==1){
            orderIds=order.getId().toString();
        }

        result.put("payAmount",countDto.getPayAmount());//本次付款金额
        result.put("sendAmount",countDto.getSendAmount());//运费
        result.put("orderIds",orderIds);//需要支付的订单
        result.put("receiveName",receiveName);//收获信息
        result.put("receiveMobile",receiveMobile);//收获信息
        result.put("receiveAddress",receiveAddress);//收获信息
        result.put("isNeedToPay",isNeedToPay);//订单是否需要支付
        //result.put("type",member.getUserType());//1,订单2,余额充值
        result.put("info","isNeedToPay标识是否需要支付。0否，1是。");



        return result;
    }

    @Transactional
    public Map<String,Object> createOrderPad(Long salesManId, List<Long> cartIds,
                                          Integer sendType,String nickName,String mobile,String code,String address,
                                          String remark){
        Map<String,Object> result = new HashMap<String,Object>();
        String orderIds = "";//需要支付的订单
        Integer isNeedToPay=1;//订单是否需要支付。默认是
        String orderNo=null;
        //1校验参数签名
        //2获取购物车数据
        MdlCountDto countDto =countService.countCart(salesManId,cartIds,null,sendType);
        //准备订单数据
        MdlOrder order = new MdlOrder();
        SundayMember salesMan = memberService.getById(salesManId);
        //2.1，商城订单
            logger.info("--订单开始生成--pad订单");
            /*if(sendType==null){
                throw new ErrorException("请选择配送方式。");
            }*/
            orderNo= NumberUtil.generateNumber("MALL");

            if(address==null||address==""){
                throw new ErrorException("缺少地址。");
            }


            logger.info("商城订单--"+orderNo+"需要支付，开始创建");
            isNeedToPay=1;
            order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DFK);



        order.setOrderNo(orderNo);
        order.setType(countDto.getType());
        order.setTotalAmount(countDto.getTotalAmount());
        order.setPayAmount(countDto.getPayAmount());
        order.setSendType(sendType);
        order.setSendAmount(countDto.getSendAmount());
        order.setReceiveName(nickName);
        order.setReceiveMobile(mobile);
        order.setReceiveAddress(address);
        order.setSalesManId(salesManId);
        order.setSalesManName(salesMan.getNickName());
        SundayMember agent=memberService.getById(salesMan.getAgentId());
        order.setAgentId(agent.getId());
        order.setAgentName(agent.getNickName());
        SundayMember member=memberService.getOneByMobile(mobile,code,salesMan);
        order.setMemberId(member.getId());
        order.setMemberName(member.getNickName());
        order.setRemark(remark);

        //保存订单
        super.insert(order);
        //保存订单商品
        List<Long> productIds=new ArrayList<Long>();
        //本次销售的商品数量
        List<Integer> sale_nums=new ArrayList<Integer>();
        List<MdlOrderProduct> orderProducts = new ArrayList<MdlOrderProduct>();
        for(MdlCountProductDto countProductDto:countDto.getProducts()){
            MdlOrderProduct orderProduct =
                    new MdlOrderProduct(order.getId(),countProductDto.getId(),
                            countProductDto.getPrice(), countProductDto.getName(),countProductDto.getNumber(),
                            countProductDto.getImage(),
                            countProductDto.getStandard(),countProductDto.getNum(), countProductDto.getType());
            orderProductMapper.insert(orderProduct);
            productIds.add(orderProduct.getProductId());
            sale_nums.add(orderProduct.getNum());
            orderProducts.add(orderProduct);
        }
        //删除购物车
        cartService.deleteCart(cartIds,salesManId,null);
        //返回支付的订单ID集合
        if(isNeedToPay==1){
            orderIds=order.getId().toString();
        }

        result.put("payAmount",countDto.getPayAmount());//本次付款金额
        result.put("sendAmount",countDto.getSendAmount());//运费
        result.put("orderIds",orderIds);//需要支付的订单
        result.put("receiveName",nickName);//收获信息
        result.put("receiveMobile",mobile);//收获信息
        result.put("receiveAddress",address);//收获信息
        result.put("isNeedToPay",isNeedToPay);//订单是否需要支付
        //result.put("type",member.getUserType());//1,订单2,余额充值
        result.put("info","isNeedToPay标识是否需要支付。0否，1是。");



        return result;
    }

    /**
     * 分页获取订单
     * @param request
     * @param memberId
     * @param type, 1,采购订单，2积分订单，3，用户自己的商城订单，
     * @param orderStatuses 0，全部，1,待付款，2待配送，3配送中，4待评价，
     * @return
     */
    public List<MdlOrderDto> selectOrder(HttpServletRequest request, Long memberId, Integer type, List<Integer> orderStatuses){
        Map<String,Object> param = ParamUtil.packageMysqlPageParam(request,"orderNo","createTime_start","createTime_end");
        SundayMember member=memberService.getById(memberId);
        //用户为销售员
        if(member.getUserType()==SundayCommonConstants.USER_TYPE_SALESMAN){
            param.put("salesManId",memberId);
            //用户为代理商  查询下级用户的
        }else if(type==SundayCommonConstants.type_mall&&member.getUserType()==SundayCommonConstants.USER_TYPE_AGENT){
            List<Long> memberIds=new ArrayList<Long>();
            Map<String ,Object> memberParam=new HashMap<String,Object>();
            memberParam.clear();
            memberParam.put("isDeleted",SundayCommonConstants.NO);
            memberParam.put("agentId",member.getId());
            List<SundayMember> members=memberService.list(memberParam);
            if(ListUtil.isNotNull(members)){
                for(SundayMember member1:members){
                    memberIds.add(member1.getId());
                }
                param.put("memberIds",memberIds);
            }else {
                throw new ErrorException("当前代理商没有下级");
            }
        }else {
            param.put("memberId",memberId);
        }

        param.put("type",type);
        if(ListUtil.isNotNull(orderStatuses)){
            if(orderStatuses.get(0)!=0){
                param.put("orderStatuses",orderStatuses);
            }
        }
        return pakageDtoMuilt(super.select(param));
    }
    /**
     * 查询订单详情
     * @param orderId
     * @param memberId
     * @return
     */
    public MdlOrderDto findOne(Long orderId,Long memberId){
        return pakageDtoSingle(super.find(orderId),null);
    }

    /**
     * 取消订单
     * @param orderId
     * @param memberId
     * @return
     */
    public void cancelOrder(Long orderId,Long memberId){

        MdlOrder order= super.find(orderId);
        //用户的商城订单，待付款允许取消
        String msg=null;
        if(order.getOrderStatus()!=SundayCommonConstants.ORDER_STATUS_DFK){
            msg="非待付款订单，不能取消";
        }
        if(StringUtils.isNotEmpty(msg)){
            throw new ErrorException(msg);
        }
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YQX);
        super.update(order);
    }

    /**
     * 代理商确认收款
     * @param orderId
     * @param confirmMessage
     */
    public void confirmOrder(Long orderId,String  confirmMessage){
        MdlOrder order=super.find(orderId);
        if(order.getType()==SundayCommonConstants.type_mall){

            SundayMember member=memberService.getById(order.getMemberId());
            //生成销售员收益
            if(LongUtil.isNotZreo(member.getRecommenderId())){
                SundayMember salesMan=memberService.getById(member.getRecommenderId());
                incomeService.updateIncome(salesMan.getId(),order.getPayAmount(),order,SundayCommonConstants.INCOME_TYPE_BUSINESS);
            }
            //生成代理商收益
            incomeService.updateIncome(member.getAgentId(),order.getPayAmount(),order,SundayCommonConstants.INCOME_TYPE_BUSINESS);
        }
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_DPS);
        order.setConfirmTime(new Date());
        order.setConfirmMessage(confirmMessage);
        super.update(order);
    }
    /**
     * 商城订单发货
     * @param orderId
     */
    @Transactional
    public void sendOrder(Long orderId){
        MdlOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_DPS,"非待配送订单，不能发货",null);
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_PSZ);
        order.setSendTime(new Date());
        super.update(order);
    }
    /**
     * 确认收货
     * @param orderId
     * @param memberId
     * @return
     */
    @Transactional
    public void confirmReceive(Long orderId,Long memberId){


        MdlOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_PSZ,"非配送中订单，不能确认收货",memberId);
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YSH);
        order.setReceiveTime(new Date());

        //生成收益，
        //生成用户赠送积分(实付款+余额抵扣)
       /* if(order.getType()==SundayCommonConstants.type_mall){
            //SundayScoreConfig scoreConfig =scoreConfigService.findOne(null);
            BigDecimal thisAmount = order.getPayAmount();
            if(order.getBalancePayAmount()!=null){
                thisAmount.add(order.getBalancePayAmount());
            }
            memberService.changeScore(order.getOrderNo(),thisAmount, SundayCommonConstants.SCORE_TYPE_REWARD,memberId);
        }*/
        super.update(order);
    }
    /**
     * 评论订单
     * @param orderId
     * @param productIds
     * @param contents
     * @param scores
     * @param images 图片集合，固定大小=productIds集合大小*3。。每个商品限制最大传入三张，没有图片的使用noImage字符传固定值。
     * @param memberId
     */
    public void  commentOrder(Long orderId,List<Long> productIds,List<String> contents,List<Integer> scores,List<String> images,Long memberId){
        String msg ="";
        if(ListUtil.isNull(productIds)||ListUtil.isNull(contents)||ListUtil.isNull(scores)){
            msg="评论接口参数有错误(为空)";
        }
        if(productIds.size()!=contents.size()||productIds.size()!=scores.size()||contents.size()!=scores.size()){
            msg="评论接口参数有错误（参数不对应）";
        }
        if(productIds.size()*3!=images.size()){
            msg="评论接口参数有错误（图片参数）";
        }
        if(msg!=""){
            throw new ErrorException(msg);
        }


        MdlOrder order=checkOrder(orderId,SundayCommonConstants.ORDER_STATUS_YSH,"非待评论订单，不能评论",memberId);
        SundayMember member = memberService.getById(memberId);
        commentService.generateComment(productIds,
                contents,
                scores,
                images,
                memberId,
                member.getImage(),
                member.getNickName(),
                SundayProduct.class.getSimpleName());

        //更改订单状态
        order.setOrderStatus(SundayCommonConstants.ORDER_STATUS_YPJ);
        super.update(order);

    }


    /**
     * 校验订单信息
     * @param orderId
     * @param status
     * @param msg
     * @param memberId
     * @return
     */
    public MdlOrder checkOrder(Long orderId,Integer status,String msg,Long memberId){
        MdlOrder order =super.find(orderId);
        if(status!=null&&order.getOrderStatus()!=status){
            throw new ErrorException(msg);
        }
        if(LongUtil.isNotZreo(memberId)&&order.getMemberId().longValue()!=memberId){
            throw new ErrorException("数据错误，请重试");
        }
        return order;
    }
    /**
     * 组装DTO
     * @param order
     * @return
     */
    public MdlOrderDto pakageDtoSingle(MdlOrder order, List<MdlOrderProductDto> products){
        if(ListUtil.isNull(products)){
            Map<String,Object> param =new HashMap<String ,Object>();
            param.put("orderId",order.getId());
            products=new ArrayList<MdlOrderProductDto>();
            for(MdlOrderProduct orderProduct:orderProductMapper.select(param)){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    products.add(new MdlOrderProductDto(
                            orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum(), orderProduct.getType()));
                }
            }

        }
        String payTime= order.getPayTime()!=null? TimeUtils.format(order.getPayTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String sendTime= order.getSendTime()!=null?TimeUtils.format(order.getSendTime(),"yyyy-MM-dd HH:mm:ss"):null;
        String receiveTime= order.getReceiveTime()!=null?TimeUtils.format(order.getReceiveTime(),"yyyy-MM-dd HH:mm:ss"):null;
        return new MdlOrderDto(order.getId(),order.getCreateTime(),order.getCreateDate(),
                order.getOrderNo(), order.getType(), order.getTotalAmount(), order.getPayAmount(),
                order.getPayNo(), order.getOrderStatus(), order.getReceiveName(),order.getReceiveMobile(), order.getReceiveAddress(),
                order.getSendAmount(),order.getRemark(),
                payTime,sendTime, receiveTime,  products);

    }

    /**
     * 组装多个
     * @param orders
     * @return
     */
    public List<MdlOrderDto> pakageDtoMuilt(List<MdlOrder> orders){
        List<MdlOrderDto> dtos= new ArrayList<MdlOrderDto>();
        List<Long> orderIds = new ArrayList<>();
        for(MdlOrder order:orders){
            orderIds.add(order.getId());
        }
        Map<String,Object> param =new HashMap<String ,Object>();
        param.put("orderIds",orderIds);
        List<MdlOrderProduct> orderProducts = orderProductMapper.select(param);
        for(MdlOrder order:orders){
            List<MdlOrderProductDto> ps = new ArrayList<MdlOrderProductDto>();
            for(MdlOrderProduct orderProduct:orderProducts){
                if(orderProduct.getOrderId().longValue()==order.getId()){
                    ps.add(new MdlOrderProductDto(orderProduct.getProductId(),orderProduct.getCreateTime(),orderProduct.getCreateDate(),
                            orderProduct.getPrice(), orderProduct.getName(), orderProduct.getNumber(),orderProduct.getImage(),
                            orderProduct.getStandard(), orderProduct.getNum(), orderProduct.getType()));
                }
            }
            MdlOrderDto dto = pakageDtoSingle(order, ps);
            dto.setSendType(order.getSendType());
            dtos.add(dto);
        }
        return dtos;
    }


}
